package com.chen.blue.oa;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.chen.blue.dictionary.AuditDict;
import com.chen.blue.dictionary.ResourceType;
import com.chen.blue.dictionary.VersionDict;
import com.chen.blue.domain.model.business.*;
import com.chen.blue.exception.e.DtoNullException;
import com.chen.blue.oa.status.OaStatus;
import com.chen.blue.service.business.*;
import com.chen.blue.service.candidate.CandidateInfoService;
import com.chen.blue.service.security.SecurityService;
import com.chen.blue.service.system.ISysDictDataService;
import com.chen.blue.utils.SpringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created By CLT On 2024/5/29.
 */
@SuppressWarnings("all")
public abstract class AbstractOaRequestHandler {

    protected final IContestApplyActiveService iContestApplyActiveService = SpringUtil.getBean("iContestApplyActiveService");

    protected final IResourceService iResourceService = SpringUtil.getBean("iResourceService");

    protected final IContestApplyRecordService iContestApplyRecordService = SpringUtil.getBean("iContestApplyRecordService");

    protected final IContestApplyService iContestApplyService = SpringUtil.getBean("iContestApplyService");

    protected final ICompetitionService iCompetitionService = SpringUtil.getBean("iCompetitionService");

    protected final ICompetitionItemService iCompetitionItemService = SpringUtil.getBean("iCompetitionItemService");

    protected final IContestPersonInfoHistoryService iContestPersonInfoHistoryService = SpringUtil.getBean("iContestPersonInfoHistoryService");

    protected final IContestPersonInfoService iContestPersonInfoService = SpringUtil.getBean("iContestPersonInfoService");

    protected final IContestResourceHistoryService iContestResourceHistoryService = SpringUtil.getBean("iContestResourceHistoryService");

    protected final IContestResultHistoryService iContestResultHistoryService = SpringUtil.getBean("iContestResultHistoryService");

    protected final IContestResultService iContestResultService = SpringUtil.getBean("iContestResultService");

    protected final OaStatus oaStatus = new OaStatus();

    protected Map<String, Integer> auditRules = new HashMap<>();

    protected AbstractOaRequestHandler handler;

    protected String role;

    public void setRole(String role) {
        this.role = role;
    }

    public AbstractOaRequestHandler setHandler(AbstractOaRequestHandler handler) {
        this.handler = handler;
        return this;
    }

    /**
     * 处理审批请求（赛事申请）
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean handlerRquest(OaRequest request) throws DtoNullException {

        return auditCrossLevel(request, AuditDict.STAGE_STAGE_FIRST);

    }

    /**
     * 处理审批请求（人员信息）
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean handlerRequestPersonInfo(OaRequest request) throws DtoNullException {

        return auditCrossLevel(request, AuditDict.STAGE_STAGE_SECOND);

    }


    /**
     * 处理审批请求（竞赛结果）
     *
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean handlerRequestContestResult(OaRequest request) throws DtoNullException {

        return auditCrossLevel(request, AuditDict.STAGE_STAGE_THIRD);

    }


    /**
     * 审核状态更新及版本更新
     *
     * @param stageCurrent
     * @param personAudit
     * @param auditStatus
     * @param stageCurrentStatus
     * @param model
     * @throws DtoNullException
     */
    protected void setStatusAndVersion(Integer stageCurrent,
                                       Integer personAudit,
                                       Integer auditStatus,
                                       Integer stageCurrentStatus,
                                       ContestApplyRecordModel model) throws DtoNullException {

        if (Objects.isNull(model)) return;

        // 防止再次审核
        if (stageCurrent.equals(model.getStageCurrent()) &&
                personAudit.equals(model.getPersonAudit()) &&
                auditStatus.equals(model.getAuditStatus()) &&
                stageCurrentStatus.equals(model.getStageCurrentStatus()))
            throw new DtoNullException("请不要重复审核");


        model.setStageCurrent(stageCurrent);
        model.setPersonAudit(personAudit);
        model.setAuditStatus(auditStatus);
        model.setStageCurrentStatus(stageCurrentStatus);
        model.setCreateTime(new Date());

        CandidateInfoService.setCreator(model);

        double aDouble = Double.parseDouble(model.getVersion());
        // 每审核一次都会更新小版本
        model.setVersion(String.format("%.1f", aDouble + VersionDict.VERSION_SMALL_STEP));

    }

    /**
     * 设置修改的条件
     *
     * @param wrapper
     */
    protected void setUpdateWrapper(UpdateWrapper<ContestApplyActiveModel> wrapper,
                                    Long id,
                                    Integer stageCurrent,
                                    Integer personAudit,
                                    Integer auditStatus,
                                    Integer stageCurrentStatus) {

        wrapper.eq("id", id);
        wrapper.set("stage_current", stageCurrent);
        wrapper.set("person_audit", personAudit);
        wrapper.set("audit_status", auditStatus);
        wrapper.set("stage_current_status", stageCurrentStatus);
        wrapper.set("updater", SecurityService.currentUserName());

    }

    /**
     * 根据当前活动表ID获取相关的活动记录的最新版本的数据
     *
     * @param id
     * @return
     */
    protected ContestApplyRecordModel getLastVersion(Long id) {

        Map<String, Object> wrap = new HashMap<>();
        wrap.put("relation", id);
        List<ContestApplyRecordModel> contestApplyRecordModelList = iContestApplyRecordService.listByMap(wrap);
        return contestApplyRecordModelList.stream().filter(obj ->
                obj.getVersion().equals(getLastVersion(contestApplyRecordModelList.stream().map(var1 -> var1.getVersion()).collect(Collectors.toList())))
        ).collect(Collectors.toList()).get(0);

    }

    /**
     * 返回申请记录中的最新版本
     *
     * @param versions
     * @return
     */
    protected String getLastVersion(List<String> versions) {

        if (Objects.isNull(versions)) {
            return null;
        }

        return String.valueOf(versions.stream().mapToDouble(Double::valueOf).max().getAsDouble());

    }

    /**
     * BeanCopy忽略字段
     *
     * @return
     */
    protected String[] ignoreAttribute() {

        return new String[]{"updater", "createTime", "updateTime", "deleted"};

    }

    /**
     * 防止跨级跨阶段审核
     *
     * @param oaRequest
     * @return
     * @throws DtoNullException
     */
    protected Boolean auditCrossLevel(OaRequest request, Integer stage) throws DtoNullException {

        ContestApplyActiveModel currentActive = iContestApplyActiveService.getById(request.getId());
        if (Objects.isNull(currentActive)) return false;

        // 不可跨阶段审核
        Integer stageCurrent = currentActive.getStageCurrent();
        if (!stageCurrent.equals(stage)) throw new DtoNullException("不可跨阶段审核");

        // 不可跨级审核
        Integer personAudit = currentActive.getPersonAudit();
        Map<String, Integer> auditRules = oaStatus.getAuditRules();
        Set<String> roleCodes = auditRules.keySet();
        for (String roleCode : roleCodes) {
            if (this.role.equals(roleCode)) {
                if (!auditRules.get(roleCode).equals(personAudit)) throw new DtoNullException("不可跨级审核");
            }
        }

        return true;

    }

    /**
     * 记录当前审核记录的人员信息，方便后续查看（一般是第二阶段）
     *
     * @param activeId
     * @param recordModel
     * @return
     */
    protected Boolean recordPersonInfoHistory(Long activeId, ContestApplyRecordModel recordModel) {

        LambdaQueryWrapper<ContestPersonInfoModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContestPersonInfoModel::getActiveId, activeId);
        List<ContestPersonInfoModel> contestPersonInfoModelList = iContestPersonInfoService.list(wrapper);

        List<ContestPersonInfoHistoryModel> temp = new ArrayList<>();
        ContestPersonInfoHistoryModel contestPersonInfoHistoryModel = null;
        for (ContestPersonInfoModel contestPersonInfoModel : contestPersonInfoModelList) {
            contestPersonInfoHistoryModel = new ContestPersonInfoHistoryModel();
            BeanUtils.copyProperties(contestPersonInfoModel, contestPersonInfoHistoryModel, new String[]{"creator", "updater", "createTime", "updateTime", "deleted"});
            contestPersonInfoHistoryModel.setRecordId(recordModel.getId());
            temp.add(contestPersonInfoHistoryModel);
        }

        return iContestPersonInfoHistoryService.saveBatch(temp);

    }

    /**
     * 记录当前审核记录的资源信息，方便后续查看（一般是第一阶段）
     *
     * @param activeId
     * @param recordModel
     * @return
     */
    protected Boolean recordResourceInfoHistory(Long activeId, ContestApplyRecordModel recordModel) {

        LambdaQueryWrapper<ResourceModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ResourceModel::getActiveId, activeId);
        wrapper.eq(ResourceModel::getType, ResourceType.RESOURCE_TYPE_FIRST);
        List<ResourceModel> resourceModelList = iResourceService.list(wrapper);

        List<ContestResourceHistoryModel> temp = new ArrayList<>();
        ContestResourceHistoryModel contestResourceHistoryModel = null;
        for (ResourceModel resourceModel : resourceModelList) {
            contestResourceHistoryModel = new ContestResourceHistoryModel();
            BeanUtils.copyProperties(resourceModel, contestResourceHistoryModel, new String[]{"creator", "updater", "createTime", "updateTime", "deleted"});
            contestResourceHistoryModel.setRecordId(recordModel.getId());
            temp.add(contestResourceHistoryModel);
        }

        return iContestResourceHistoryService.saveBatch(temp);

    }

    /**
     * 记录当前审核记录的结果信息，方便后续查看（一般是第三阶段）
     *
     * @param activeId
     * @param recordModel
     * @return
     */
    protected Boolean recordResultInfoHistory(Long activeId, ContestApplyRecordModel recordModel) {

        LambdaQueryWrapper<ContestResultModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ContestResultModel::getActiveId, activeId);
        List<ContestResultModel> contestResultModelList = iContestResultService.list(wrapper);

        List<ContestResultHistoryModel> temp = new ArrayList<>();
        ContestResultHistoryModel contestResultHistoryModel = null;
        for (ContestResultModel contestResultModel : contestResultModelList) {
            contestResultHistoryModel = new ContestResultHistoryModel();
            BeanUtils.copyProperties(contestResultModel, contestResultHistoryModel, new String[]{"creator", "updater", "createTime", "updateTime", "deleted"});
            contestResultHistoryModel.setRecordId(recordModel.getId());
            temp.add(contestResultHistoryModel);
        }

        return iContestResultHistoryService.saveBatch(temp);

    }

}
